package Fp

import (
	"crypto/sha256"
	"fmt"
	"db2s/full"
	"db2s/go-log/log"
	"db2s/parDef"
	"db2s/ref"
	"math"
	"math/big"
	"reflect"
	"strings"
	"sync/atomic"
	"time"
	"unicode/utf8"
)

func md5Hash(s string) (m string) {
	hash := sha256.Sum256([]byte(s))
	m = fmt.Sprintf("%x", hash)
	return
}
func nullCompareActive(s1, s2 string) (b bool, r int) {
	switch {
	case s1 == "<null>" && s2 == "<null>":
		b = true
		r = 0
	case s1 == "<null>":
		b = true
		r = -1
	case s2 == "<null>":
		b = true
		r = 1
	}
	return
}

// timeLayoutParse 判断时间类型字符串是否带时区
func timeZoneLayoutIf(t1 string) (b bool) {
	var (
		timeLayoutError = "2006-01-02 15:04:05 -0700 MST"
		err             error
	)
	if _, err = time.Parse(t1, timeLayoutError); err == nil {
		return true
	}
	return false
}

// 解析时间字符串为 time.Time 类型
func timeZoneLayoutParse(t1 string) (t time.Time, err error) {
	var (
		timeLayoutError = "2006-01-02 15:04:05 -0700 MST"
	)
	loc, _ := time.LoadLocation("Local")
	if t, err = time.ParseInLocation(timeLayoutError, t1, loc); err != nil {
		//errorActive(fmt.Sprintf("(%d) %s time Parse fail, error info is {%v} layout is {%v} timeStr is {%v} time Parse is {%v}", logSeq, event, err, timeLayoutError, t1, t))
		return
	}
	return
}
func timeLayoutParse(t1 string) (t time.Time, err error) {
	var (
	//event      = "[timeParse]"
	)
	var timeLayout = "2006-01-02 15:04:05"
	if t, err = time.Parse(timeLayout, t1); err != nil {
		//errorActive(fmt.Sprintf("(%d) %s time Parse fail, error info is {%v} layout is {%v} timeStr is {%v} time Parse is {%v}", logSeq, event, err, timeLayoutError, t1, t))
		return
	}
	return
}

// TimeParse 先把时间字符串格式化成相同的时间类型
func TimeParse(t1 string) (t time.Time, err error) {
	if timeZoneLayoutIf(t1) { //字符串带时区
		return timeZoneLayoutParse(t1)
	}
	return timeLayoutParse(t1)
}

/*
TimeCompare 时间类型的值比较
*/
func TimeCompare(t1, t2 string) (r int, err error) {
	var (
		r1, r2 time.Time
	)
	//先把时间字符串格式化成相同的时间类型
	if b, c := nullCompareActive(t1, t2); b {
		return c, err
	}
	if t1 == t2 {
		return 0, err
	}
	if r1, err = TimeParse(t1); err != nil {
		return
	}
	if r2, err = TimeParse(t2); err != nil {
		return
	}
	if r1.Before(r2) {
		return -1, err
	}
	return 1, err
}

/*
stringToInt  字符串转数值类型
*/
func stringToInt(valueType, sss string) (any, error) {
	switch valueType {
	case "int", "int64":
		num := new(big.Int)
		num.SetString(sss, 10)
		return num, nil
	case "float64", "decimal":
		c, _ := new(big.Float).SetString(sss)
		return c, nil
	default:
		num := new(big.Int)
		num.SetString(sss, 10)
		return num, nil
	}
}

/*
intValueTypeOptimizer  字符串转数值类型
*/
func intValueTypeOptimizer(l1, l2 any) (t string) {
	t1, t2 := fmt.Sprintf("%v", reflect.TypeOf(l1)), fmt.Sprintf("%v", reflect.TypeOf(l2))
	if strings.EqualFold(t1, t2) {
		return t1
	}
	switch {
	case strings.EqualFold(t1, "*big.Int") || strings.EqualFold(t2, "*big.Int"):
		t = "*big.Int"
	case strings.EqualFold(t1, "*big.Float") || strings.EqualFold(t2, "*big.Float"):
		t = "*big.Float"
	default:
		t = t1
	}
	return
}
func decimalCompare(i1, i2 any) (r int, err error) {
	epsilon := 0.0001
	i11 := i1.(float64)
	i22 := i2.(float64)
	if math.Abs(i11-i22) < epsilon {
		r = 0
	} else if i11 < i22 {
		r = -1
	} else {
		r = 1
	}
	return
}
func int64Compare(i1, i2 any) (r int, err error) {
	i11 := i1.(int64)
	i22 := i2.(int64)
	if i11 > i22 {
		r = 1
	} else if i11 == i22 {
		r = 0
	} else {
		r = -1
	}
	return
}
func bigint64Compare(i1, i2 any) (r int, err error) {
	var i11, i22 *big.Int
	if !strings.EqualFold(fmt.Sprintf("%s", reflect.TypeOf(i1)), "*big.Int") {
		i11 = big.NewInt(0).SetInt64(i1.(int64))
	} else {
		i11 = i1.(*big.Int)
	}
	if !strings.EqualFold(fmt.Sprintf("%s", reflect.TypeOf(i2)), "*big.Int") {
		i22 = big.NewInt(0).SetInt64(i2.(int64))
	} else {
		i22 = i2.(*big.Int)
	}
	r = i11.Cmp(i22)
	return
}
func bigFloatCompare(i1, i2 any) (r int, err error) {
	var i11, i22 *big.Float
	if !strings.EqualFold(fmt.Sprintf("%s", reflect.TypeOf(i1)), "*big.Float") {
		//i11 = big.NewInt(0).SetInt64(i1.(int64))
	} else {
		i11 = i1.(*big.Float)
	}
	if !strings.EqualFold(fmt.Sprintf("%s", reflect.TypeOf(i2)), "*big.Float") {
		//i22 = big.NewInt(0).SetInt64(i2.(int64))
	} else {
		i22 = i2.(*big.Float)
	}
	r = i11.Cmp(i22)
	return
}
func valueStringToInt(cn, s1, s2 string) (i []any, err error) {
	i = make([]any, 2)
	for k, v := range []string{s1, s2} {
		var i1 any
		if i1, err = stringToInt(cn, v); err != nil {
			return
		}
		i[k] = i1
	}
	return
}

// IntCompare int类型的比较
func IntCompare(cn, s1, s2 string) (r int, err error) {
	var (
		result []any
	)
	if b, c := nullCompareActive(s1, s2); b {
		return c, nil
	}
	if result, err = valueStringToInt(cn, s1, s2); err != nil {
		return 0, err
	}
	switch intValueTypeOptimizer(result[0], result[1]) {
	case "float64", "decimal":
		return decimalCompare(result[0], result[1])
	case "int64":
		return int64Compare(result[0], result[1])
	case "*big.Int":
		return bigint64Compare(result[0], result[1])
	case "*big.Float":
		return bigFloatCompare(result[0], result[1])
	}
	return
}

func compareOracleRowIdBase64(str1, str2 string) int {
	base64Chars := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	str1 = strings.TrimRight(str1, "=")
	str2 = strings.TrimRight(str2, "=")
	for i := 0; i < len(str1) && i < len(str2); i++ {
		charIndex1 := strings.IndexByte(base64Chars, str1[i])
		charIndex2 := strings.IndexByte(base64Chars, str2[i])
		if charIndex1 < charIndex2 {
			return -1
		} else if charIndex1 > charIndex2 {
			return 1
		}
	}
	if len(str1) < len(str2) {
		return -1
	} else if len(str1) > len(str2) {
		return 1
	}
	return 0
}

/*
compareUTF8Strings 比较utf8
*/
func compareUTF8Strings(str1, str2 string) int {
	var min = func(a, b int) int {
		if a < b {
			return a
		}
		return b
	}
	count1 := utf8.RuneCountInString(str1)
	count2 := utf8.RuneCountInString(str2)
	minCount := min(count1, count2)
	for i := 0; i < minCount; i++ {
		r1, _ := utf8.DecodeRuneInString(str1)
		r2, _ := utf8.DecodeRuneInString(str2)
		if r1 < r2 {
			return -1
		} else if r1 > r2 {
			return 1
		}
		str1 = str1[utf8.RuneLen(r1):]
		str2 = str2[utf8.RuneLen(r2):]
	}
	if count1 < count2 {
		return -1
	} else if count1 > count2 {
		return 1
	}
	return 0
}

// oRowIdBase64 oracle RowIdBase64 比较
func oRowIdBase64(str1, str2 string) (int, error) {
	base64Chars := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	str1 = strings.TrimRight(str1, "=")
	str2 = strings.TrimRight(str2, "=")
	for i := 0; i < len(str1) && i < len(str2); i++ {
		charIndex1 := strings.IndexByte(base64Chars, str1[i])
		charIndex2 := strings.IndexByte(base64Chars, str2[i])
		if charIndex1 < charIndex2 {
			return -1, nil
		} else if charIndex1 > charIndex2 {
			return 1, nil
		}
	}
	if len(str1) < len(str2) {
		return -1, nil
	} else if len(str1) > len(str2) {
		return 1, nil
	}
	return 0, nil
}
func strLengthMin(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// UTF8Strings utf8包含中文、特殊字符、字符串比较
func UTF8Strings(str1, str2 string) (int, error) {
	if b, c := nullCompareActive(str1, str2); b {
		return c, nil
	}
	count1 := utf8.RuneCountInString(str1)
	count2 := utf8.RuneCountInString(str2)
	minCount := strLengthMin(count1, count2)
	for i := 0; i < minCount; i++ {
		r1, _ := utf8.DecodeRuneInString(str1)
		r2, _ := utf8.DecodeRuneInString(str2)
		if r1 < r2 {
			return -1, nil
		} else if r1 > r2 {
			return 1, nil
		}
		str1 = str1[utf8.RuneLen(r1):]
		str2 = str2[utf8.RuneLen(r2):]
	}
	if count1 < count2 {
		return -1, nil
	} else if count1 > count2 {
		return 1, nil
	}
	return 0, nil
}
func CollationStrings(full full.Full) (result int, err error) {
	var res any
	if res, err = full.GetFullStringValueCompare(); err != nil {
		return
	}
	result = int(res.(int64))
	return
}

/*
ValueCompare 值进行比较比较，判断第一个值是否大于第二个值
*/
func ValueCompare(full full.Full, col []string, s []string) (r int, err error) {
	defer func() {
		if err != nil {
			r = 2
		}
	}()
	switch col[1] {
	case "numerical", "int", "int16", "int8", "int32", "int64", "float64", "decimal":
		if r, err = IntCompare(col[1], s[0], s[1]); err != nil {
			return
		}
	//case "string", "char", "varchar":
	//	if r, err = UTF8Strings(s1, s2); err != nil {
	//		return 2, err
	//	}
	case "rowId":
		if r, err = oRowIdBase64(s[0], s[1]); err != nil {
			return
		}
	case "datetime", "time", "timestamp":
		if r, err = TimeCompare(s[0], s[1]); err != nil {
			return
		}
	default:
		full.Parameter1[0].Meta = map[string][]string{col[0]: s}
		if r, err = CollationStrings(full); err != nil {
			return
		}
	}
	return
}
func eqSymbol(direction, v string, minScope, eqNull bool) (p string) {
	switch direction {
	case "left":
		if eqNull && strings.EqualFold(v, "NULL") {
			return "="
		}
		if minScope {
			p = ">="
			return
		}
		p = ">"
		return

	case "right":
		if eqNull && strings.EqualFold(v, "NULL") {
			p = "="
		} else {
			if minScope {
				p = "<="
				return
			}
			p = "<"
			return
		}
	}
	return
}
func sliceAnyCopy(a any) (q any) {
	switch fmt.Sprintf("%v", reflect.TypeOf(a)) {
	case "[]map[string]string":
		var l []map[string]string
		if a != nil {
			for _, v := range a.([]map[string]string) {
				l = append(l, v)
			}
		}
		q = l
	}
	return
}
func nullValue(v string) (p string) {
	if v == "<null>" {
		p = "NULL"
	} else {
		p = v
	}
	return
}
func nullMeta(cdn []string) map[int]int {
	var (
		nullMark = make(map[int]int) //索引列的null值标记序号
	)
	for k, v := range cdn {
		if strings.EqualFold(v, "YES") {
			nullMark[k] = 0
		}
	}
	return nullMark
}

func swapErrorPoint(code *int64) {
	if code != nil {
		atomic.SwapInt64(code, -1)
	}
}
func debugActive(str string) {
	log.ScheduleLog().DebugS(str)
	//writeLogActive("debug", str)
}
func infoActive(str string) {
	log.ScheduleLog().InfoS(str)
	//writeLogActive("info", str)
}
func warnActive(str string) {
	log.ScheduleLog().WarnS(str)
	//writeLogActive("warn", str)
}
func errorActive(str string) {
	log.ErrorLog().ErrorS(str)
	//writeLogActive("error", str)
}

func swapLoopFrequency(old *int64, val int64) {
	atomic.SwapInt64(old, val)
}
func (sp TaskDistribution) whereGenerateInit() parDef.WhereGenerateInput {
	var (
		boolS                         int32
		leftDirection, rightDirection atomic.Value
	)
	var nullYes = true
	for _, v := range getNullValue(sp.First.Null) {
		if strings.EqualFold(v, "YES") {
			nullYes = false
		}
	}
	if !nullYes {
		boolS = 1
	}
	return parDef.WhereGenerateInput{
		ColMetaMap:     sp.Object.Column,
		NullBool:       &boolS,
		NullConstraint: "not null",
		LeftDirection:  &leftDirection,
		RightDirection: &rightDirection,
	}
}
func limitInit() parDef.LimitOffset {
	var (
		pagination int64
		modifyS    int32
	)
	return parDef.LimitOffset{
		Pagination: &pagination,
		ModifyS:    &modifyS,
	}
}

/*
初始化output 传参对象
*/
func (sp TaskDistribution) pOutputInit() *parDef.IndexPart {
	p := &parDef.IndexPart{
		WhereGenerate: sp.whereGenerateInit(),
		Limit:         limitInit(),
		NewIndexCol:   sp.getFirstNameStringSlice(),
	}
	return p
}

/*
初始化input 传参对象
*/
func (sp TaskDistribution) pInputInit() parDef.IndexPart {
	return parDef.IndexPart{
		WhereGenerate: sp.whereGenerateInit(),
		Limit:         limitInit(),
	}
}
func (sp TaskDistribution) indexColumnValueActive(result any, parameter parDef.Parameter) (value []string) {
	var (
		row map[string]any
		//vlog  string
		//event = "[indexColumnValueActive]"
	)
	//vlog = fmt.Sprintf("(%v) %v get index chunk start Data success of table %v.%v(%v). result is {indexColumn:%v rowData:%v}", logSeq, event, sp.TableObject.Schema, sp.TableObject.Table, sp.TableObject.PartitionName, sp.indexCol, row)
	//debugActive(vlog)
	switch result.(type) {
	case map[string]any:
		row = result.(map[string]any)
	default:
		return
	}
	for _, v := range parameter.Object.Index.ColumnMate {
		for k1, v1 := range row {
			if strings.EqualFold(k1, fmt.Sprintf("C%v", v.ColumnSeq)) {
				//vlog = fmt.Sprintf("(%d)  %v The index column value of table %v.%v(%v) is %v index column name is %v", logSeq, event, sp.TableObject.Schema, sp.TableObject.Table, sp.TableObject.PartitionName, v1, v)
				//debugActive(vlog)
				value = append(value, fmt.Sprintf("%v", v1))
			}
		}
	}
	return
}

/*
IndexChunkStart 源目标端索引分段查询的结果
*/
func (sp TaskDistribution) IndexChunkStart(full full.Full, parameter parDef.Parameter) (sdr []string, status bool, err error) {
	var (
		result any
	)
	if result, err = full.GetFullIndexPartST(); err != nil {
		err = ref.ErrAddPrintf("Fp.IndexChunkStart", err)
		return
	}
	value := sp.indexColumnValueActive(result, parameter)
	if len(value) == 0 {
		return nil, false, nil
	}
	return value, true, nil
}
func (sp TaskDistribution) queryObjectSource(s parDef.IndexPart, parameter parDef.Parameter) (chunkStartV []string, status bool, err error) {
	parameter.Meta = s
	parameter.Object.IndexCol = s.NewIndexCol
	sp.Full.Parameter1 = []parDef.Parameter{parameter}
	return sp.IndexChunkStart(sp.Full, parameter)
}
func (sp TaskDistribution) queryObjectDest(s parDef.IndexPart, parameter parDef.Parameter) (chunkStartV []string, status bool, err error) {
	parameter.Meta = s
	return sp.IndexChunkStart(sp.Full, parameter)
}
func (sp TaskDistribution) queryObjectAll(s parDef.IndexPart, srcParameter, dstParameter parDef.Parameter) (res [][]string, status []bool, err error) {
	var (
		sv, dv   []string
		ok1, ok2 bool
	)
	if sv, ok1, err = sp.queryObjectSource(s, srcParameter); err != nil {
		return
	}
	if dv, ok2, err = sp.queryObjectDest(s, dstParameter); err != nil {
		return
	}
	res = append(res, sv, dv)
	status = append(status, ok1, ok2)
	return
}

func (sp TaskDistribution) IndexChunkObject(s parDef.IndexPart, logSeq int64) (chunkStartV []string, err error) {
	var (
		event = "[IndexChunkObject]"
		vlog  string
		//res    [][]string
		//status []bool
	)
	vlog = fmt.Sprintf("(%d) %v Start the first-level segmentation of table %v.%v.", logSeq, event, sp.TableObject.Schema, sp.TableObject.Table)
	debugActive(vlog)
	switch sp.DataSource {
	case "src":
		chunkStartV, _, err = sp.queryObjectSource(s, sp.SrcParameter)
	case "dst":
		chunkStartV, _, err = sp.queryObjectDest(s, sp.DstParameter)
	case "all":
		//if res, status, err = sp.queryObjectAll(s, sp.SrcParameter, sp.DstParameter); err != nil {
		//	return
		//}
		//switch {
		//case status[0] && status[1]:
		//	chunkStartV, err = sp.minValueCompare(s, res[0], res[1])
		//case status[0] && !status[1]:
		//	chunkStartV = res[0]
		//case !status[0] && status[1]:
		//	chunkStartV = res[1]
		//}
	}
	vlog = fmt.Sprintf("(%d) %v The first-level segmentation of table %v.%v is successful. result is {%v} error is {%v}", logSeq, event, sp.TableObject.Schema, sp.TableObject.Table, chunkStartV, err)
	debugActive(vlog)
	return
}
func (sp TaskDistribution) getSegmentationData(inputValue parDef.IndexPart, modifyValue *atomic.Value) (err error) {
	var (
		event = "[getSegmentationData]"
		wc    []string
	)
	if wc, err = sp.IndexChunkObject(inputValue, sp.LogSeq); err != nil {
		errorActive(fmt.Sprintf("(%d-%v) %v setup3&: An abnormal error is detected in table %v.%v(%v) and the parallel segmented query mechanism is exited.error is {%v}", sp.LogSeq, sp.getFirstSemLogSeq(), event, sp.TableObject.Schema, sp.TableObject.Table, sp.TableObject.PartitionName, err))
		swapErrorPoint(sp.ErrEnd)
		return
	}
	swapAtomicValue(modifyValue, wc)
	return
}

func generalColumnCondition(columnName, direction, columnData, querySymbol string) map[string]string {
	var (
		columnDataResult = map[string]string{
			"columnName": columnName,
		}
	)
	switch direction {
	case "left":
		columnDataResult["columnDataLeft"] = columnData
		columnDataResult["querySymbolLeft"] = querySymbol
	case "right":
		columnDataResult["columnDataRight"] = columnData
		columnDataResult["querySymbolRight"] = querySymbol
	}
	return columnDataResult
}

func (sp TaskDistribution) resultNullValueActive(symbol, oldValue, newValue string, k1 int) (left, right map[string]string) {
	if strings.EqualFold(symbol, ">=") && (oldValue == "NULL" && newValue == "NULL") { //null 值合并
		querySymbolLeft, querySymbolRight := "=", "="
		left = generalColumnCondition(sp.getFirstNameStringSlice()[k1], "left", oldValue, querySymbolLeft)
		right = generalColumnCondition(sp.getFirstNameStringSlice()[k1], "right", newValue, querySymbolRight)
	}
	return
}
func (sp TaskDistribution) prefix(vl valueLocationInput) (whereLeft, []whereRight) {
	var (
		whereRightGather                                         []whereRight
		pLeftGather, pRightGather, swsLeftGather, swsRightGather []map[string]string
		nullBool                                                 int32
	)
	for k1, v1 := range vl.wc {
		oldValue, newValue := nullValue(vl.ws[k1]), nullValue(v1)
		var querySymbolLeft string
		if int64(k1) == vl.k {
			querySymbolLeft = ">"
			for k := range vl.nullMark {
				if vl.k < int64(k) {
					atomic.SwapInt32(&nullBool, 1)
					break
				}
			}
			querySymbolLeft = ">"
			pLeftGather = append(pLeftGather, generalColumnCondition(vl.indexCol[k1], "left", oldValue, querySymbolLeft))
			pRightGather = append(pRightGather, generalColumnCondition(vl.indexCol[k1], "right", newValue, "<="))
			swsLeftGather = append(swsLeftGather, generalColumnCondition(vl.indexCol[vl.k], "left", vl.wc[vl.k], ">"))
			whereRightGather = append(whereRightGather, whereRight{
				pLeft:      pLeftGather,
				pRight:     pRightGather,
				compareSeq: vl.k,
				Segment:    1,
				NullBool:   &nullBool,
			})
		}
	}
	return whereLeft{swsLeft: swsLeftGather, swsRight: swsRightGather}, whereRightGather
}
func nullConstraintIf(vl valueLocationInput) (nullBool int32) {
	for k := range vl.nullMark {
		if vl.k < int64(k) {
			atomic.SwapInt32(&nullBool, 1)
			break
		}
	}
	return
}
func (sp TaskDistribution) middle(vl valueLocationInput) (whereLeft, []whereRight) {
	swsRes := sp.swsResult(vl)
	return whereLeft{swsLeft: swsRes.left, swsRight: swsRes.right}, sp.resResult(vl)
}
func (sp TaskDistribution) swsResult(vl valueLocationInput) (res swsValueResult) {
	for k1, v1 := range vl.wc {
		oldValue, newValue := nullValue(vl.ws[k1]), nullValue(v1)
		if int64(k1) < vl.k {
			leftSymbol, rightSymbol := eqSymbol("left", oldValue, true, true), eqSymbol("right", newValue, true, true)
			res.left = append(res.left, generalColumnCondition(vl.indexCol[k1], "left", oldValue, leftSymbol))
			res.right = append(res.right, generalColumnCondition(vl.indexCol[k1], "right", newValue, rightSymbol))
		} else if int64(k1) == vl.k {
			leftSymbol := eqSymbol("left", newValue, false, false)
			res.left = append(res.left, generalColumnCondition(vl.indexCol[k1], "left", newValue, leftSymbol))
		}
	}
	return
}
func (sp TaskDistribution) resNotNullSymbolActive(vl valueLocationInput, pLeftGather, pRightGather []map[string]string, col, old, new, symbol string) whereRight {
	nullBool := nullConstraintIf(vl)
	pLeftGather = append(pLeftGather, generalColumnCondition(col, "left", old, symbol))
	pRightGather = append(pRightGather, generalColumnCondition(col, "right", new, "<="))
	return whereRight{
		pLeft:      pLeftGather,
		pRight:     pRightGather,
		compareSeq: vl.k,
		Segment:    vl.Segment,
		NullBool:   &nullBool,
	}
}
func (sp TaskDistribution) resMinNullSymbolActive(vl valueLocationInput, pLeftGather, pRightGather []map[string]string, col, old string) whereRight {
	nullBool := nullConstraintIf(vl)
	pLeftGather = append(pLeftGather, generalColumnCondition(col, "left", old, "="))
	return whereRight{
		pLeft:      pLeftGather,
		pRight:     pRightGather,
		compareSeq: vl.k,
		Segment:    vl.Segment,
		NullBool:   &nullBool,
	}
}
func (sp TaskDistribution) resMaxNullSymbolActive(vl valueLocationInput, pLeftGather, pRightGather []map[string]string, col, old, new string) whereRight {
	nullBool := nullConstraintIf(vl)
	pLeftGather = append(pLeftGather, generalColumnCondition(col, "left", old, ">"))
	pRightGather = append(pRightGather, generalColumnCondition(col, "right", new, "<="))
	return whereRight{
		pLeft:      pLeftGather,
		pRight:     pRightGather,
		compareSeq: vl.k,
		Segment:    vl.Segment,
		NullBool:   &nullBool,
	}
}
func (sp TaskDistribution) resNullSymbolActive(vl valueLocationInput, pLeftGather, pRightGather []map[string]string, col, old, new string) (res []whereRight) {
	for _, j := range []string{"min", "max"} {
		newLeftGather := sliceAnyCopy(pLeftGather).([]map[string]string)
		newRightGather := sliceAnyCopy(pRightGather).([]map[string]string)
		switch j {
		case "min":
			res = append(res, sp.resMinNullSymbolActive(vl, newLeftGather, newRightGather, col, old))
		case "max":
			res = append(res, sp.resMaxNullSymbolActive(vl, newLeftGather, newRightGather, col, old, new))
		}
	}
	return
}
func (sp TaskDistribution) resResult(vl valueLocationInput) (res []whereRight) {
	var (
		pLeftGather, pRightGather []map[string]string
	)
	for k1, v1 := range vl.wc {
		oldValue, newValue := nullValue(vl.ws[k1]), nullValue(v1)
		if int64(k1) < vl.k {
			leftSymbol, rightSymbol := eqSymbol("left", oldValue, true, true), eqSymbol("right", newValue, true, true)
			pLeftGather = append(pLeftGather, generalColumnCondition(vl.indexCol[k1], "left", oldValue, leftSymbol))
			pRightGather = append(pRightGather, generalColumnCondition(vl.indexCol[k1], "right", newValue, rightSymbol))
		} else if int64(k1) == vl.k {
			querySymbolLeft := eqSymbol("left", oldValue, false, false)
			switch querySymbolLeft {
			case "=":
			case ">=":
				switch {
				case oldValue == "NULL": //首行，包含null值，且是>= null and <= not null
					return sp.resNullSymbolActive(vl, pLeftGather, pRightGather, vl.indexCol[k1], oldValue, newValue)
				case newValue == "NULL": //不可能出现
				default:
					return append(res, sp.resNotNullSymbolActive(vl, pLeftGather, pRightGather, vl.indexCol[k1], oldValue, newValue, querySymbolLeft))
				}
			case ">":
				return append(res, sp.resNotNullSymbolActive(vl, pLeftGather, pRightGather, vl.indexCol[k1], oldValue, newValue, querySymbolLeft))
			}
		}
	}
	return
}

func (sp TaskDistribution) suffix(vl valueLocationInput) (whereLeft, []whereRight) {
	swsRes := sp.swsResult(vl)
	return whereLeft{swsLeft: swsRes.left, swsRight: swsRes.right}, sp.resResult(vl)
}
func (sp TaskDistribution) first(vl valueLocationInput) (whereLeft, []whereRight) {
	var (
		whereRightGather                                         []whereRight
		pLeftGather, pRightGather, swsLeftGather, swsRightGather []map[string]string
	)
	vl.Segment = 1
	for k1, v1 := range vl.wc {
		oldValue, newValue := nullValue(vl.wc[k1]), nullValue(v1)
		if k1 < len(vl.wc)-1 {
			leftSymbol, rightSymbol := eqSymbol("left", oldValue, true, true), eqSymbol("right", newValue, true, true)
			swsLeftGather = append(swsLeftGather, generalColumnCondition(vl.indexCol[k1], "left", oldValue, leftSymbol))
			swsRightGather = append(swsRightGather, generalColumnCondition(vl.indexCol[k1], "right", newValue, rightSymbol))
		} else {
			leftSymbol := eqSymbol("left", oldValue, false, false)
			swsLeftGather = append(swsLeftGather, generalColumnCondition(vl.indexCol[k1], "left", oldValue, leftSymbol))
		}
		pLeftGather = append(pLeftGather, generalColumnCondition(vl.indexCol[k1], "left", oldValue, "="))
		pRightGather = append(pRightGather, generalColumnCondition(vl.indexCol[k1], "right", oldValue, "="))
	}
	whereRightGather = append(whereRightGather, whereRight{
		pLeft:      pLeftGather,
		pRight:     pRightGather,
		compareSeq: vl.k,
		Segment:    vl.Segment,
	})
	return whereLeft{
		swsLeft:  swsLeftGather,
		swsRight: swsRightGather,
	}, whereRightGather
}

func swapLimitPagination(old *int64, val int64) {
	if old != nil {
		atomic.SwapInt64(old, val)
	}
}
func getWsValue(old *atomic.Value) (res []string) {
	if old == nil {
		return
	}
	val := getAtomicValue(old)
	if val == nil {
		return []string{}
	}
	return val.([]string)
}
func getWcValue(old *atomic.Value) (res []string) {
	if old == nil {
		return
	}
	val := getAtomicValue(old)
	if val == nil {
		return []string{}
	}
	return val.([]string)
}

// firstGetLeftDirection
func getLeftDirection(old *atomic.Value) (res []map[string]string) {
	if old == nil {
		return
	}
	val := getAtomicValue(old)
	if val == nil {
		return nil
	}
	return val.([]map[string]string)
}
func getRightDirection(old *atomic.Value) (res []map[string]string) {
	if old == nil {
		return
	}
	val := getAtomicValue(old)
	switch val.(type) {
	case []map[string]string:
		return val.([]map[string]string)
	}
	return
}

func getLastModifyPoint(lastModifyPoint *int64) int64 {
	return atomic.LoadInt64(lastModifyPoint)
}

func swapAtomicValue(old *atomic.Value, val any) {
	if old == nil {
		return
	}
	old.Store(val)
}
func getAtomicValue(old *atomic.Value) (res any) {
	if old == nil {
		return
	}
	return old.Load()
}
func (sp TaskDistribution) swapLastModifyPoint(val int64) {
	//atomic.SwapInt64(sp.First.Batch.WhereGenerate.LastModifyPoint, val)
}
func (sp TaskDistribution) swapNullBoolValue(val int32) {
	atomic.SwapInt32(sp.First.Batch.WhereGenerate.NullBool, val)
}
func (sp TaskDistribution) swapNameStringSlice(old *atomic.Value, val []string) {
	if old == nil {
		return
	}
	old.Store(val)
}
func (sp TaskDistribution) getFirstNameStringSlice() (res []string) {
	if sp.First.Name == nil {
		return
	}
	return sp.First.Name.Load().([]string)
}
func (sp TaskDistribution) getSecondNameStringSlice() (res []string) {
	if sp.Second.Name == nil {
		return
	}
	return sp.Second.Name.Load().([]string)
}
func (sp TaskDistribution) getNullBoolValue() bool {
	switch atomic.LoadInt32(sp.First.Batch.WhereGenerate.NullBool) {
	case 0:
		return false
	case 1:
		return true
	default:
		return false
	}
}

func (sp TaskDistribution) getTwoValueCompare(s inputConditionalS) (r string, err error) {
	var (
		segmentCompareValue []int
	)
	if len(getTypeValue(s.Type)) > 0 && len(getWsValue(s.WS)) == 0 && len(getWcValue(s.WC)) > 0 { //首行
		return "first", nil
	}
	if segmentCompareValue, err = newColumnValue(s.full, getTypeValue(s.Name), getTypeValue(s.Type), getWcValue(s.WC), getWsValue(s.WS)); err != nil {
		return
	}
	sum := 0
	for k, v := range segmentCompareValue {
		atomic.SwapInt64(s.CompareSeq, int64(k))
		sum += v
		switch {
		case v == 1 && k == 0: //处理前导列、单列就出现大于，
			return "prefix", nil
		case v == 1 && k < len(segmentCompareValue)-1: //处理非第一次循环的联合索引场景
			sp.First.LastModifyPoint = k
			return "middle", nil
		case v == 1 && k == len(segmentCompareValue)-1 && sum == 1: //多列索引，且是最后一列的索引值，且是大于值
			return "suffix", nil
		case v == 0 && k == len(segmentCompareValue)-1 && sum == 0:
			return "first", nil
		}
	}
	return "notValue", nil
}

func (sp TaskDistribution) getConditionalFuncReflectValue() map[string]reflect.Value {
	return map[string]reflect.Value{
		"prefix": reflect.ValueOf(sp.prefix),
		"middle": reflect.ValueOf(sp.middle),
		"suffix": reflect.ValueOf(sp.suffix),
		"first":  reflect.ValueOf(sp.first),
	}
}
func (sp TaskDistribution) conditionalValue(s inputConditionalS) (res1 whereLeft, res2 []whereRight, err error) {
	var site string
	if site, err = sp.getTwoValueCompare(s); err != nil {
		return
	}
	if fun, ok := sp.getConditionalFuncReflectValue()[site]; ok {
		args := []reflect.Value{
			reflect.ValueOf(valueLocationInput{
				k:        atomic.LoadInt64(s.CompareSeq),
				ws:       sp.firstGetWsValue(),
				wc:       sp.firstGetWcValue(),
				indexCol: sp.getFirstNameStringSlice(),
			}),
		}
		q := fun.Call(args)
		res1 = q[0].Interface().(whereLeft)
		res2 = q[1].Interface().([]whereRight)
	}
	return
}
